package com.z.system.init;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import com.z.system.model.Permission;
import com.z.system.model.PermissionType;
import com.z.system.model.Role;
import com.z.system.model.User;
import com.z.system.repository.PermissionRepository;
import com.z.system.repository.RoleRepository;
import com.z.system.repository.UserRepository;

/**
 * 数据初始化类，用于系统启动时创建初始用户、角色和权限
 */
@Component
public class DataInitializer implements CommandLineRunner {

    private static final Logger logger = LoggerFactory.getLogger(DataInitializer.class);

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private PermissionRepository permissionRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void run(String... args) throws Exception {
        logger.info("开始初始化系统数据...");

        // 初始化权限
        initPermissions();

        // 初始化角色
        Role adminRole = initRoles();

        // 初始化用户
        User adminUser = initUsers();

        // 使用原生SQL建立用户和角色的关联
        if (adminUser != null && adminRole != null) {
            initUserRoleRelations(adminUser, adminRole);
        }

        logger.info("系统数据初始化完成");
    }

    private void initPermissions() {
        // 检查是否已存在权限数据
        if (permissionRepository.count() > 0) {
            logger.info("权限数据已存在，跳过初始化");
            return;
        }

        logger.info("开始初始化权限数据...");

        // 初始化菜单权限数据（从asyncRoutes.ts转换）
        List<Permission> allPermissions = initMenuPermissions();

        // 分离已保存的模块权限和未保存的页面权限
        List<Permission> modulePermissions = new ArrayList<>();
        List<Permission> pagePermissions = new ArrayList<>();

        for (Permission permission : allPermissions) {
            if (permission.getType().equals(PermissionType.MODULE)) {
                modulePermissions.add(permission);
            } else if (permission.getType().equals(PermissionType.PAGE)) {
                pagePermissions.add(permission);
            }
        }

        // 保存页面权限
        List<Permission> savedPagePermissions = permissionRepository.saveAll(pagePermissions);

        // 合并所有已保存的权限
        List<Permission> savedMenuPermissions = new ArrayList<>();
        savedMenuPermissions.addAll(modulePermissions); // 模块权限已经保存过
        savedMenuPermissions.addAll(savedPagePermissions);

        // 验证菜单权限的parentId设置是否正确
        for (Permission permission : savedMenuPermissions) {
            if (permission.getType().equals(PermissionType.MODULE)) { // 模块权限
                logger.debug("模块权限: {}, ID: {}, ParentId: {}", permission.getName(), permission.getId(),
                        permission.getParentId());
            } else if (permission.getType().equals(PermissionType.PAGE)) { // 页面权限
                logger.debug("页面权限: {}, ID: {}, ParentId: {}", permission.getName(), permission.getId(),
                        permission.getParentId());
            }
        }

        // 创建角色管理相关权限
        // 查找角色管理页面权限
        Permission rolePagePermission = null;
        for (Permission permission : savedMenuPermissions) {
            if ("sys:role".equals(permission.getPermission())) {
                rolePagePermission = permission;
                break;
            }
        }

        Permission roleViewPermission = createPermission("sys:role:view", "查看角色", PermissionType.BUTTON,
                rolePagePermission != null ? rolePagePermission.getId() : null);
        Permission roleCreatePermission = createPermission("sys:role:create", "创建角色", PermissionType.BUTTON,
                rolePagePermission != null ? rolePagePermission.getId() : null);
        Permission roleUpdatePermission = createPermission("sys:role:update", "更新角色", PermissionType.BUTTON,
                rolePagePermission != null ? rolePagePermission.getId() : null);
        Permission roleDeletePermission = createPermission("sys:role:delete", "删除角色", PermissionType.BUTTON,
                rolePagePermission != null ? rolePagePermission.getId() : null);

        // 创建用户管理相关权限
        // 查找用户管理页面权限
        Permission userPagePermission = null;
        for (Permission permission : savedMenuPermissions) {
            if ("sys:user".equals(permission.getPermission())) {
                userPagePermission = permission;
                break;
            }
        }

        Permission userViewPermission = createPermission("sys:user:view", "查看用户", PermissionType.BUTTON,
                userPagePermission != null ? userPagePermission.getId() : null);
        Permission userCreatePermission = createPermission("sys:user:create", "创建用户", PermissionType.BUTTON,
                userPagePermission != null ? userPagePermission.getId() : null);
        Permission userUpdatePermission = createPermission("sys:user:update", "更新用户", PermissionType.BUTTON,
                userPagePermission != null ? userPagePermission.getId() : null);
        Permission userDeletePermission = createPermission("sys:user:delete", "删除用户", PermissionType.BUTTON,
                userPagePermission != null ? userPagePermission.getId() : null);

        // 创建菜单管理相关权限
        // 查找菜单管理页面权限
        Permission menuPagePermission = null;
        for (Permission permission : savedMenuPermissions) {
            if ("sys:menu".equals(permission.getPermission())) {
                menuPagePermission = permission;
                break;
            }
        }

        Permission menuViewPermission = createPermission("sys:menu:view", "查看菜单", PermissionType.BUTTON,
                menuPagePermission != null ? menuPagePermission.getId() : null);
        Permission menuCreatePermission = createPermission("sys:menu:create", "创建菜单", PermissionType.BUTTON,
                menuPagePermission != null ? menuPagePermission.getId() : null);
        Permission menuUpdatePermission = createPermission("sys:menu:update", "更新菜单", PermissionType.BUTTON,
                menuPagePermission != null ? menuPagePermission.getId() : null);
        Permission menuDeletePermission = createPermission("sys:menu:delete", "删除菜单", PermissionType.BUTTON,
                menuPagePermission != null ? menuPagePermission.getId() : null);

        // 收集所有按钮权限
        List<Permission> buttonPermissions = new ArrayList<>();
        buttonPermissions.addAll(
                Arrays.asList(roleViewPermission, roleCreatePermission, roleUpdatePermission, roleDeletePermission));
        buttonPermissions.addAll(
                Arrays.asList(userViewPermission, userCreatePermission, userUpdatePermission, userDeletePermission));
        buttonPermissions.addAll(
                Arrays.asList(menuViewPermission, menuCreatePermission, menuUpdatePermission, menuDeletePermission));

        // 保存按钮权限
        permissionRepository.saveAll(buttonPermissions);

        // 添加日志记录，验证parentId设置
        logger.debug("成功初始化 {} 个菜单权限和 {} 个按钮权限", savedMenuPermissions.size(), buttonPermissions.size());

        logger.info("权限数据初始化完成");
    }

    /**
     * 初始化菜单权限数据（从asyncRoutes.ts转换）
     */
    private List<Permission> initMenuPermissions() {
        List<Permission> allPermissions = new ArrayList<>();
        List<Permission> modulePermissions = new ArrayList<>();

        // 1. 创建所有模块权限（顶级菜单）
        Permission dashboardPermission = createMenuPermission("sys:dashboard", "Dashboard", PermissionType.MODULE,
                "dashboard", null, "&#xe721;");
        dashboardPermission.setTitle("menus.dashboard.title");
        dashboardPermission.setComponent("RoutesAlias.Layout"); // 布局组件使用/index/index
        dashboardPermission.setSort(0);
        Permission systemPermission = createMenuPermission("sys:system", "System", PermissionType.MODULE, "system",
                null, "&#xe7b9;");
        systemPermission.setTitle("menus.system.title");
        systemPermission.setComponent("RoutesAlias.Layout"); // 布局组件使用/index/index
        systemPermission.setSort(1);

        Permission resultPermission = createMenuPermission("sys:result", "Result", PermissionType.MODULE, "result",
                null, "&#xe715;");
        resultPermission.setTitle("menus.result.title");
        resultPermission.setComponent("RoutesAlias.Layout"); // 布局组件使用/index/index
        resultPermission.setSort(2);

        Permission exceptionPermission = createMenuPermission("sys:exception", "Exception", PermissionType.MODULE,
                "exception", null, "&#xe820;");
        exceptionPermission.setTitle("menus.exception.title");
        exceptionPermission.setComponent("RoutesAlias.Layout"); // 布局组件使用/index/index
        exceptionPermission.setSort(3);

        modulePermissions.add(dashboardPermission);
        modulePermissions.add(systemPermission);
        modulePermissions.add(resultPermission);
        modulePermissions.add(exceptionPermission);

        // 先保存模块权限，获取真实ID
        List<Permission> savedModulePermissions = permissionRepository.saveAll(modulePermissions);

        // 更新引用，使用真实保存后的模块权限对象
        for (Permission savedModule : savedModulePermissions) {
            if (savedModule.getPermission().equals(dashboardPermission.getPermission())) {
                dashboardPermission = savedModule;
            } else if (savedModule.getPermission().equals(systemPermission.getPermission())) {
                systemPermission = savedModule;
            } else if (savedModule.getPermission().equals(resultPermission.getPermission())) {
                resultPermission = savedModule;
            } else if (savedModule.getPermission().equals(exceptionPermission.getPermission())) {
                exceptionPermission = savedModule;
            }
        }

        // 添加保存后的模块权限到总列表
        allPermissions.addAll(savedModulePermissions);

        // 2. 创建所有页面权限，并使用保存后的模块ID作为parentId

        // 仪表盘子菜单
        Permission consolePermission = createMenuPermission("sys:dashboard:console", "Console", PermissionType.PAGE,
                "/dashboard/console", dashboardPermission.getId(), null);
        consolePermission.setTitle("menus.dashboard.console");
        // consolePermission.setComponent("RoutesAlias.Dashboard"); //
        // 直接使用RoutesAlias.Dashboard前端属性字段
        // 设置特定属性值 - 参照asyncRoutes.ts
        consolePermission.setFixedTab(true); // 固定标签页

        // 系统子菜单
        Permission userPermission = createMenuPermission("sys:user", "User", PermissionType.PAGE, "/system/user",
                systemPermission.getId(), null);
        userPermission.setTitle("menus.system.user");
        // userPermission.setComponent("RoutesAlias.User"); //
        // 直接使用RoutesAlias.User前端属性字段
        // 设置特定属性值 - 参照asyncRoutes.ts
        userPermission.setKeepAlive(true); // 启用缓存

        Permission rolePermission = createMenuPermission("sys:role", "Role", PermissionType.PAGE, "/system/role",
                systemPermission.getId(), null);
        rolePermission.setTitle("menus.system.role");
        // rolePermission.setComponent("RoutesAlias.Role"); //
        // 直接使用RoutesAlias.Role前端属性字段
        // 设置特定属性值 - 参照asyncRoutes.ts
        rolePermission.setKeepAlive(true); // 启用缓存

        Permission userCenterPermission = createMenuPermission("sys:user-center", "UserCenter", PermissionType.PAGE,
                "/system/user-center", systemPermission.getId(), null);
        userCenterPermission.setTitle("menus.system.userCenter");
        userCenterPermission.setHide(true); // 隐藏菜单
        userCenterPermission.setHideTab(true); // 隐藏标签页
        userCenterPermission.setKeepAlive(true); // 启用缓存
        // userCenterPermission.setComponent("RoutesAlias.UserCenter"); //
        // 直接使用RoutesAlias.UserCenter前端属性字段

        // 添加菜单管理权限
        Permission menuPermission = createMenuPermission("sys:menu", "Menu", PermissionType.PAGE,
                "/system/menu", systemPermission.getId(), null);
        menuPermission.setTitle("menus.system.menu");
        menuPermission.setKeepAlive(true); // 启用缓存
        // menuPermission.setComponent("RoutesAlias.Menu"); //
        // 直接使用RoutesAlias.Menu前端属性字段

        // 根据前端路由数组添加Swagger权限
        Permission swaggerPermission = createMenuPermission("sys:system:swagger", "Swagger", PermissionType.PAGE,
                "/system/swagger", systemPermission.getId(), "&#xe62a;");
        swaggerPermission.setTitle("menus.system.swagger");
        swaggerPermission.setKeepAlive(true); // 启用缓存
        // swaggerPermission.setComponent("RoutesAlias.Swagger"); //
        // 直接使用RoutesAlias.Swagger前端属性字段

        // 结果子菜单
        Permission successPermission = createMenuPermission("sys:result:success", "ResultSuccess", PermissionType.PAGE,
                "/result/success", resultPermission.getId(), null);
        successPermission.setTitle("menus.result.success");
        successPermission.setKeepAlive(true); // 启用缓存
        // successPermission.setComponent("RoutesAlias.Success"); //
        // 直接使用RoutesAlias.Success前端属性字段

        Permission failPermission = createMenuPermission("sys:result:fail", "ResultFail", PermissionType.PAGE,
                "/result/fail",
                resultPermission.getId(), null);
        failPermission.setTitle("menus.result.fail");
        failPermission.setKeepAlive(true); // 启用缓存
        // failPermission.setComponent("RoutesAlias.Fail"); //
        // 直接使用RoutesAlias.Fail前端属性字段

        // 异常子菜单
        Permission forbiddenPermission = createMenuPermission("sys:exception:403", "403", PermissionType.PAGE,
                "/exception/403", exceptionPermission.getId(), null);
        forbiddenPermission.setTitle("menus.exception.forbidden");
        forbiddenPermission.setKeepAlive(true); // 启用缓存
        forbiddenPermission.setOpenType(1); // 全屏显示
        // forbiddenPermission.setComponent("RoutesAlias.Exception403"); //
        // 直接使用RoutesAlias.Exception403前端属性字段

        Permission notFoundPermission = createMenuPermission("sys:exception:404", "404", PermissionType.PAGE,
                "/exception/404", exceptionPermission.getId(), null);
        notFoundPermission.setTitle("menus.exception.notFound");
        notFoundPermission.setKeepAlive(true); // 启用缓存
        notFoundPermission.setOpenType(1); // 全屏显示
        // notFoundPermission.setComponent("RoutesAlias.Exception404"); //
        // 直接使用RoutesAlias.Exception404前端属性字段

        Permission serverErrorPermission = createMenuPermission("sys:exception:500", "500", PermissionType.PAGE,
                "/exception/500", exceptionPermission.getId(), null);
        serverErrorPermission.setTitle("menus.exception.serverError");
        serverErrorPermission.setKeepAlive(true); // 启用缓存
        serverErrorPermission.setOpenType(1); // 全屏显示
        // serverErrorPermission.setComponent("RoutesAlias.Exception500"); //
        // 直接使用RoutesAlias.Exception500前端属性字段

        // 添加所有页面权限到总列表
        allPermissions.addAll(Arrays.asList(
                consolePermission,
                userPermission,
                rolePermission,
                userCenterPermission,
                menuPermission,
                swaggerPermission,
                successPermission,
                failPermission,
                forbiddenPermission,
                notFoundPermission,
                serverErrorPermission));

        return allPermissions;
    }

    /**
     * 创建菜单类型的权限
     */
    private Permission createMenuPermission(String permission, String name, Integer type, String href, UUID parentId,
            String icon) {
        Permission p = new Permission();
        p.setPermission(permission);
        p.setName(name);
        p.setType(type); // PermissionType.MODULE, PermissionType.PAGE, PermissionType.BUTTON
        p.setHref(href);
        p.setParentId(parentId);
        p.setIcon(icon != null ? icon : "");
        p.setCreateTime(new Date());
        p.setEnable(1);
        p.setSort(1); // 默认排序

        // 设置默认属性值，参照前端路由配置
        // 页面缓存 - 默认false
        p.setKeepAlive(false);
        // 是否固定标签页 - 默认false
        p.setFixedTab(false);
        // 是否全屏 - 默认false
        p.setOpenType(0); // 0: 普通页面, 1: 全屏显示
        // 是否隐藏菜单 - 默认false
        p.setHide(false);
        // 是否隐藏标签页 - 默认false
        p.setHideTab(false);

        return p;
    }

    private Role initRoles() {
        // 检查是否已存在角色数据
        Role adminRole;
        if (roleRepository.count() > 0) {
            logger.info("角色数据已存在，检查admin角色");
            adminRole = roleRepository.findByName("admin").orElse(null);
        } else {
            logger.info("开始初始化角色数据...");

            // 创建管理员角色
            adminRole = new Role();
            adminRole.setName("Super");
            adminRole.setCode("ADMIN");
            adminRole.setCreateTime(new Date());

            // 保存角色
            adminRole = roleRepository.save(adminRole);

            logger.info("角色数据初始化完成");
        }

        // 确保admin角色拥有所有权限
        if (adminRole != null) {
            // 获取所有权限
            List<Permission> permissions = permissionRepository.findAll();

            // 清空现有权限关联（避免重复）
            try {
                String deleteSql = "DELETE FROM t_role_permission WHERE role_id = ?";
                jdbcTemplate.update(deleteSql, adminRole.getId());
            } catch (Exception e) {
                logger.error("清空角色已有权限失败", e);
            }

            // 使用原生SQL建立角色和权限的关联
            initRolePermissionRelations(adminRole, permissions);
        }

        return adminRole;
    }

    /**
     * 使用原生SQL初始化角色和权限的关联关系
     */
    private void initRolePermissionRelations(Role role, List<Permission> permissions) {
        if (role == null || permissions == null || permissions.isEmpty()) {
            return;
        }

        try {
            String sql = "INSERT INTO t_role_permission (role_id, permission_id) VALUES (?, ?)";

            for (Permission permission : permissions) {
                jdbcTemplate.update(sql, role.getId(), permission.getId());
            }

            logger.info("已为角色 {} 分配 {} 个权限", role.getName(), permissions.size());
        } catch (Exception e) {
            logger.error("初始化角色权限关联失败", e);
        }
    }

    private User initUsers() {
        // 检查是否已存在用户数据
        if (userRepository.count() > 0) {
            logger.info("用户数据已存在，跳过初始化");
            return userRepository.findByUserSn("Super").orElse(null);
        }

        logger.info("开始初始化用户数据...");

        // 创建管理员用户
        User adminUser = new User();
        adminUser.setUsername("admin");
        adminUser.setUserSn("Super"); // UserDetailsService是通过userSn查找用户的
        adminUser.setPassword(passwordEncoder.encode("123456"));
        adminUser.setNickname("系统管理员");
        adminUser.setEnable(1);
        adminUser.setSex(1);
        adminUser.setCreateTime(new Date());
        adminUser.setDeptId(getOrCreateDefaultDept());
        // 保存用户
        userRepository.save(adminUser);

        logger.info("用户数据初始化完成");
        logger.info("管理员账号: Super: 123456");

        return adminUser;
    }

    /**
     * 使用原生SQL初始化用户、部门和角色的关联关系
     */
    private void initUserRoleRelations(User user, Role role) {
        if (user == null || role == null) {
            return;
        }

        try {
            // 检查是否已存在关联关系
            String checkSql = "SELECT COUNT(*) FROM t_dept_user_role WHERE user_id = ? AND role_id = ?";
            Integer count = jdbcTemplate.queryForObject(checkSql, Integer.class, user.getId(), role.getId());

            if (count != null && count > 0) {
                logger.info("用户 {} 角色 {} 关联关系已存在，跳过初始化", user.getUsername(), role.getName());
                return;
            }

            // 获取或创建默认部门
            UUID deptId = getOrCreateDefaultDept();

            // 插入用户、部门和角色的关联关系
            String sql = "INSERT INTO t_dept_user_role (dept_id, user_id, role_id) VALUES (?, ?, ?)";
            jdbcTemplate.update(sql, deptId, user.getId(), role.getId());

            logger.info("已为用户 {} 分配角色 {}", user.getUsername(), role.getName());
        } catch (Exception e) {
            logger.error("初始化用户角色关联失败", e);
        }
    }

    /**
     * 获取或创建默认部门
     */
    private UUID getOrCreateDefaultDept() {
        try {
            // 检查是否存在默认部门
            String checkSql = "SELECT id FROM t_dept WHERE name = ?";
            List<UUID> deptIds = jdbcTemplate.query(checkSql, (rs, rowNum) -> rs.getObject(1, UUID.class), "集团");

            if (!deptIds.isEmpty()) {
                return deptIds.get(0);
            }

            // 如果不存在，创建默认部门
            UUID deptId = UUID.randomUUID();
            // 添加name_abbr字段以满足非空约束
            String insertSql = "INSERT INTO t_dept (id, name, code, level, sort, create_time, del, name_abbr) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
            jdbcTemplate.update(insertSql, deptId, "集团", "DEFAULT", 1, 1, new Date(), 0, "集团公司");

            return deptId;
        } catch (Exception e) {
            logger.error("获取或创建默认部门失败", e);
            // 如果创建失败，返回一个临时UUID
            return UUID.randomUUID();
        }
    }

    private Permission createPermission(String permission, String name, Integer type) {
        return createPermission(permission, name, type, null);
    }

    private Permission createPermission(String permission, String name, Integer type, UUID parentId) {
        Permission p = new Permission();
        p.setPermission(permission);
        p.setName(name);
        p.setType(type);
        p.setParentId(parentId);
        p.setCreateTime(new Date());
        p.setEnable(1);
        return p;
    }
}